package com.siecom.module;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;

import com.siecom.constconfig.ConstDefine;
import com.siecom.constconfig.ErrorDefine;
import com.siecom.hostservice.MainActivity;
import com.siecom.tool.ByteTool;
import com.siecom.tool.LogUtil;
import com.siecom.tool.Timer;
import com.siecom.transport.handler.KeyBoardHandler;

import java.io.IOException;
import java.util.List;

import static com.siecom.hostservice.MainActivity.context;

/**
 * Created by zhq on 2017/1/18.
 */

public class KeyBoardRunnable extends ModuleRunnable {
    private final static String TAG = "KeyBoardRunnable";
    public static CipherKeyBoardModule keyBoardModule = CipherKeyBoardModule.getInstance();
    private String cardNo;
    private String masterKeyIndex;
    private String workKeyIndex;
    private String pwdLen;
    private String timeOutSec;
    private int encryptMode;
    private boolean isEncrypted;
    private int enterFre;
    private int inputTimes = 1;

    public static PinEntryBroadcastReceiver mPinReceiver  ;

    public boolean isInputting() {

        if (alreadyInputlength > 0 && runFlag) {

            return true;
        }
        return false;
    }

    public int getAlreadyInputlength() {

        return alreadyInputlength;
    }

    private int alreadyInputlength = 0;

    public KeyBoardRunnable (){

    }
    public KeyBoardRunnable(String cardNo, String masterKeyIndex, String workKeyIndex, String pwdLen, String timeOutSec, int encryptMode, DeviceCallback callback, boolean isOnMain, boolean isEncrypted) {

        this.cardNo = cardNo;
        this.masterKeyIndex = masterKeyIndex;
        this.workKeyIndex = workKeyIndex;
        this.pwdLen = pwdLen;
        this.timeOutSec = timeOutSec;
        this.encryptMode = encryptMode;
        this.callback = callback;
        this.isOnMain = isOnMain;
        this.isEncrypted = isEncrypted;
        LogUtil.e(TAG,"mPinReceiver=" + mPinReceiver);
        if(mPinReceiver == null ){
            mPinReceiver = new PinEntryBroadcastReceiver();
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction("com.pos.pinentry");
            context.registerReceiver(mPinReceiver,intentFilter);
            LogUtil.e(TAG,"注册了广播 mPinReceiver=" + mPinReceiver);
        }


    }

    public void stopRun() {
        this.runFlag = false;
        keyBoardModule.setStopRun(true);
    }
    public static void unregisterPinEntryReceiver(){
        if(mPinReceiver != null){
            context.unregisterReceiver(mPinReceiver);
            mPinReceiver = null;
        }

    }

    @Override
    public void run() {
        //设置使用的密钥
        synchronized (this) {

            byte[] pinBlock = new byte[16];
            int res = -1;

            boolean runFlag = true;  // 接受密码键盘明文输入的值。

            com.pos.utils.PinContext ctx = new com.pos.utils.PinContext();

            byte [] background = new byte[3];
            byte [] font = new byte [4];
            byte [] prompt = "请输入密码:".getBytes();
            background[0] = (byte)0xff;//R
            background[1] = (byte)0xff;//G
            background[2] = (byte)0xff;//B
            font[0] = (byte)0xff;//R
            font[1] = (byte)0x00;//G
            font[2] = (byte)0xff;//B
            font[3] = 20;//text size(dp)
            ctx.setPromptLength(prompt.length);
            ctx.setFontLength(font.length);
            ctx.setBackgroundLength(background.length);
            ctx.setPrompt(prompt);
            ctx.setFont(font);
            ctx.setBackground(background);

            //设置卡号或传输码
            byte i = (byte) Integer.parseInt(workKeyIndex); //秘钥索引值为 0-5
            if(i < 0 || i >5){
                i = 0;
            }
            final byte index = i; //秘钥索引号
            int mLen = Integer.parseInt(pwdLen);
            if(mLen > 16 || mLen < 4){
                mLen = 16;
            }
            byte maxLen = (byte)mLen; //秘钥最大长度
            byte minLen = 0x04;
            byte cardNoByts[] = cardNo.getBytes();
            byte cardNoLen = (byte) cardNoByts.length;
            byte mark = 0;  // 0  显示amount   1  不显示amount
            byte amount[] = " ".getBytes();
            amount = null;
            byte waitTimeSec = 0;

            /**
             *mode   0x20| 0x04  密码不足最小长度 返回错误        0x20 密码不足最小长度 不返回   0显示带金额的输入界面
             */
            byte mode = 0x20|0x04;
            LogUtil.e(TAG,"encryptMode ==" + encryptMode);
            if(encryptMode == ConstDefine.KEY_3DES){  //密文 3DES 获取

                deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);

                //mode   0x20| 0x04  密码不足最小长度 返回错误        0x20 密码不足最小长度 不返回   0显示带金额的输入界面
                res = MainActivity.getmMainPci().DLL_PciGetPin(index, minLen, maxLen, cardNoLen, cardNoByts, mode, pinBlock, mark, null, (byte)0, ctx);
//                if(res == 0){
//                    res = MainActivity.getmMainPci().DLL_PciGetPin(index, (byte)0, (byte)0, (byte)16, cardNoByts, (byte)0x08, pinBlock,(byte)0, null, (byte)0, ctx);
//                }
                LogUtil.e(TAG,"res==" + res);
                if (res != 0) {
                    Bundle bundle = new Bundle();
//                    if(res == -7030){
//                        bundle.putInt("code", ErrorDefine.LENGTH_ERR);
//                        bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.LENGTH_ERR));
//                    }else {
                        bundle.putInt("code", ErrorDefine.SET_ENCRYPT_ERR);
                        bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.SET_ENCRYPT_ERR));
//                    }
                    deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);

                    SystemClock.sleep(100);

                    return;
                }else {
                    Bundle bundle = new Bundle();
                    bundle.putInt("flag", 0);
                    bundle.putString("data", ByteTool.bytearrayToHexString(pinBlock, 8));
                    bundle.putByteArray("pwd", pinBlock);
                    deliverResult(callback, DeviceInterface.Result.COMPLETED, bundle, isOnMain);

                }

            }else if(encryptMode == ConstDefine.KEY_SM){ //国密 SM4
                deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
//                amount = new byte[14];
//                System.arraycopy("123456.00".getBytes(), 0, amount, 0, "123456.00".getBytes().length);

                res = MainActivity.getmSm().DLL_SMGetPinSM4K(index, minLen, maxLen, cardNoLen, cardNoByts, mode, pinBlock, mark, null, (byte)30, ctx);
                LogUtil.e(TAG,"SM4 res==" + res);
                if (res != 0) {
                    Bundle bundle = new Bundle();

//                    if(res == -7030){
//                        bundle.putInt("code", ErrorDefine.LENGTH_ERR);
//                        bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.LENGTH_ERR));
//                    }else {
                        bundle.putInt("code", ErrorDefine.SET_ENCRYPT_ERR);
                        bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.SET_ENCRYPT_ERR));
//                    }
                    deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);

                    SystemClock.sleep(100);

                    return;
                }else {
                    Bundle bundle = new Bundle();
                    bundle.putInt("flag", 0);
                    bundle.putString("data", ByteTool.bytearrayToHexString(pinBlock, 16));
                    bundle.putByteArray("pwd", pinBlock);
                    deliverResult(callback, DeviceInterface.Result.COMPLETED, bundle, isOnMain);

                }

            } else { //明文
                KeyBoardHandler.plainTextInputing = true;
//                MainActivity.getmMainPci().DLL_PciKbClose();

                int openRes = MainActivity.getmMainPci().DLL_PciKbOpen();
                if(openRes != 0){
                    Bundle bundle = new Bundle();
                    bundle.putInt("code", ErrorDefine.KEYBORAD_OPEN_ERR);
                    bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.KEYBORAD_OPEN_ERR));
                    deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                }else {

                    deliverResult(callback, DeviceInterface.Result.START, null, isOnMain);
                    StringBuffer sb = new StringBuffer();
                    int alreadyInputLen = 0;
                    byte[] keyVlaue = new byte[1];
                    while (runFlag){
                        if(!KeyBoardHandler.plainTextInputing){//取消输入
                            deliverResult(callback, DeviceInterface.Result.ERROR, null, isOnMain);
                            MainActivity.getmMainPci().DLL_PciKbClose(); //关闭键盘
                            LogUtil.e(TAG," 取消了明文输入 DLL_PciKbClose" );
                            return;
                        }
                        SystemClock.sleep(100);
                        res = MainActivity.getmMainPci().DLL_PciKbGetKey(keyVlaue);
                        if(res != 0){
                            Bundle bundle = new Bundle();
                            bundle.putInt("code", ErrorDefine.KEYBORAD_OPEN_ERR);
                            bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.KEYBORAD_OPEN_ERR));
                            deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                            return;
                        }
                        if((keyVlaue[0]&0xFF) == 0xFF){
                            continue;
                        }else {
                            LogUtil.e(TAG, "接收的字符：" + (keyVlaue[0]&0xFF) + "---res =" + res );
                            if(keyVlaue[0] <= 0x39 && keyVlaue[0] >= 0x30){
                                if(alreadyInputLen < Integer.parseInt(pwdLen)){
                                    sb.append(new String(keyVlaue));
                                    alreadyInputLen ++;
                                    Bundle bundle = new Bundle();
                                    bundle.putInt("flag", 1);
                                    bundle.putInt("data", alreadyInputLen);
                                    deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
                                }

                            }else if(keyVlaue[0] == 0x1C){ //返回 （取消上一次的输入）
                                if(alreadyInputLen > 0){
                                    LogUtil.e(TAG,"sb==" + sb.toString());
                                    sb = sb.deleteCharAt(alreadyInputLen - 1);

                                    LogUtil.e(TAG,"sb==" + sb.toString());
                                    alreadyInputLen --;

                                    Bundle bundle = new Bundle();
                                    bundle.putInt("flag", 1);
                                    bundle.putInt("data", alreadyInputLen);
                                    deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
                                }
                                continue;

                            }else if(keyVlaue[0] == 0x1B){  //取消输入
                                alreadyInputLen = 0;
                                sb = new StringBuffer();
                                Bundle bundle = new Bundle();
                                bundle.putInt("code", ErrorDefine.CANCEL_INPUT);
                                bundle.putString("message", ErrorDefine.getErrorDescribe(ErrorDefine.CANCEL_INPUT));
                                deliverResult(callback, DeviceInterface.Result.ERROR, bundle, isOnMain);
                                runFlag = false;  //结束接收
                                MainActivity.getmMainPci().DLL_PciKbClose(); //关闭键盘
                            }else if (keyVlaue[0] == 0x0D){  //确认
                                if(alreadyInputLen >= Integer.parseInt(pwdLen)){
                                    runFlag = false;
                                    Bundle bundle = new Bundle();
                                    bundle.putInt("flag", 0);
                                    bundle.putString("data", sb.toString());

                                    deliverResult(callback, DeviceInterface.Result.COMPLETED, bundle, isOnMain);
                                    LogUtil.e(TAG,"按了确认 runflag = " + runFlag);
                                    MainActivity.getmMainPci().DLL_PciKbClose(); //关闭键盘
                                }

                            }
                        }
                        LogUtil.e(TAG, "接收的所有字符：" + sb.toString());
                    }

                }

            }


        }

    }



    public class PinEntryBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
//            LogUtil.e("----------------","PinEntryBroadcastReceiver----"+ intent.getAction());
            if (intent.getAction().equals("com.pos.pinentry"))
            {
                int len = intent.getIntExtra("pinLen", 0);
                Log.e("PinLen","PinLen:"+len);//len:0~12  finish:100
                  Intent newIntent = new Intent(context, MainActivity.class);
                  newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  //注意，必须添加这个标记，否则启动会失败
                  context.startActivity(newIntent);
                if(len >0 && len < 20){  //判断长度
                    Bundle bundle = new Bundle();
                    bundle.putInt("flag", 1);
                    bundle.putInt("data", len);
                    deliverResult(callback, DeviceInterface.Result.SUCCEED, bundle, isOnMain);
                }


            }
        }
    }


}
